package com.zenithmind.task.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zenithmind.common.exception.BusinessException;
import com.zenithmind.common.result.PageResult;
import com.zenithmind.common.utils.BeanCopyUtils;
import com.zenithmind.task.mapper.TaskTagMapper;
import com.zenithmind.task.pojo.entity.TaskTag;
import com.zenithmind.task.pojo.query.TaskTagQuery;
import com.zenithmind.task.pojo.vo.TaskTagVO;
import com.zenithmind.task.service.TaskTagService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 任务标签服务实现类
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class TaskTagServiceImpl extends ServiceImpl<TaskTagMapper, TaskTag> implements TaskTagService {

    @Override
    public PageResult<TaskTagVO> getTaskTagPage(TaskTagQuery query, String userId) {
        Page<TaskTag> page = query.toPage();

        LambdaQueryWrapper<TaskTag> wrapper = new LambdaQueryWrapper<>();
        wrapper.like(StringUtils.hasText(query.getKeyword()), TaskTag::getName, query.getKeyword())
               .in(query.getTagIds() != null && !query.getTagIds().isEmpty(), TaskTag::getId, query.getTagIds())
               .eq(query.getStatus() != null, TaskTag::getStatus, query.getStatus())
               .eq(StringUtils.hasText(userId), TaskTag::getCreatorId, userId);
        
        wrapper.orderByDesc(TaskTag::getCreateTime);

        IPage<TaskTag> result = page(page, wrapper);

        List<TaskTagVO> voList = result.getRecords().stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());

        return PageResult.of(voList, result.getTotal());
    }

    @Override
    public TaskTagVO getTaskTagById(String id, String userId) {
        TaskTag taskTag = getById(id);
        if (taskTag == null) {
            throw new BusinessException("任务标签不存在");
        }
        
        return convertToVO(taskTag);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean createTaskTag(TaskTag taskTag, String userId) {
        // 检查标签名称是否已存在
        LambdaQueryWrapper<TaskTag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskTag::getName, taskTag.getName())
               .eq(TaskTag::getCreatorId, userId);

        if (count(wrapper) > 0) {
            throw new BusinessException("标签名称已存在");
        }
        
        taskTag.setCreatorId(userId);
        if (taskTag.getStatus() == null) {
            taskTag.setStatus(1); // 默认启用
        }
        
        boolean result = save(taskTag);
        
        if (result) {
            log.info("用户 {} 创建任务标签: {}", userId, taskTag.getName());
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean updateTaskTag(TaskTag taskTag, String userId) {
        TaskTag existing = getById(taskTag.getId());
        if (existing == null) {
            throw new BusinessException("任务标签不存在");
        }

        // 权限检查
        if (!existing.getCreatorId().equals(userId)) {
            throw new BusinessException("无权限修改该标签");
        }

        // 检查标签名称是否已存在（排除自己）
        LambdaQueryWrapper<TaskTag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskTag::getName, taskTag.getName())
               .eq(TaskTag::getStatus, 1)
               .ne(TaskTag::getId, taskTag.getId());

        if (count(wrapper) > 0) {
            throw new BusinessException("标签名称已存在");
        }

        boolean result = updateById(taskTag);
        
        if (result) {
            log.info("用户 {} 更新任务标签: {}", userId, taskTag.getName());
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean deleteTaskTag(String id, String userId) {
        TaskTag taskTag = getById(id);
        if (taskTag == null) {
            throw new BusinessException("任务标签不存在");
        }

        // 权限检查
        if (!taskTag.getCreatorId().equals(userId)) {
            throw new BusinessException("无权限删除该标签");
        }

        // 检查是否有任务在使用该标签
        if (taskTag.getUsageCount() > 0) {
            throw new BusinessException("该标签正在被使用，无法删除");
        }

        boolean result = removeById(id);
        
        if (result) {
            log.info("用户 {} 删除任务标签: {}", userId, taskTag.getName());
        }
        
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean batchDeleteTaskTags(List<String> ids, String userId) {
        for (String id : ids) {
            deleteTaskTag(id, userId);
        }
        return true;
    }

    @Override
    public List<TaskTagVO> getAllAvailableTags(String userId) {
        LambdaQueryWrapper<TaskTag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskTag::getStatus, 1)
               .orderByDesc(TaskTag::getUsageCount)
               .orderByAsc(TaskTag::getSortOrder)
               .orderByAsc(TaskTag::getName);

        List<TaskTag> tags = list(wrapper);
        
        return tags.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }

    @Override
    public TaskTagVO getTaskTagByName(String name, String userId) {
        LambdaQueryWrapper<TaskTag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskTag::getName, name)
               .eq(TaskTag::getCreatorId, userId)
               .last("LIMIT 1");
        
        TaskTag taskTag = getOne(wrapper);
        
        return taskTag != null ? convertToVO(taskTag) : null;
    }

    @Override
    public List<TaskTagVO> getPopularTags(Integer limit, String userId) {
        LambdaQueryWrapper<TaskTag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskTag::getStatus, 1)
               .gt(TaskTag::getUsageCount, 0)
               .orderByDesc(TaskTag::getUsageCount)
               .last("LIMIT " + (limit != null ? limit : 10));

        List<TaskTag> tags = list(wrapper);
        
        return tags.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }

    @Override
    public List<TaskTagVO> getUserCreatedTags(String userId) {
        LambdaQueryWrapper<TaskTag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskTag::getCreatorId, userId)
               .eq(TaskTag::getStatus, 1)
               .orderByDesc(TaskTag::getCreateTime);

        List<TaskTag> tags = list(wrapper);
        
        return tags.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }

    @Override
    public List<TaskTagVO> searchTags(String keyword, String userId) {
        LambdaQueryWrapper<TaskTag> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(TaskTag::getStatus, 1)
               .and(w -> w.like(TaskTag::getName, keyword)
                         .or()
                         .like(TaskTag::getDescription, keyword))
               .orderByDesc(TaskTag::getUsageCount)
               .orderByAsc(TaskTag::getName);

        List<TaskTag> tags = list(wrapper);
        
        return tags.stream()
            .map(this::convertToVO)
            .collect(Collectors.toList());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Boolean mergeTags(String sourceTagId, String targetTagId, String userId) {
        TaskTag sourceTag = getById(sourceTagId);
        TaskTag targetTag = getById(targetTagId);
        
        if (sourceTag == null || targetTag == null) {
            throw new BusinessException("标签不存在");
        }

        // 权限检查
        if (!sourceTag.getCreatorId().equals(userId) || !targetTag.getCreatorId().equals(userId)) {
            throw new BusinessException("无权限合并标签");
        }

        // 更新目标标签的使用次数
        targetTag.setUsageCount(targetTag.getUsageCount() + sourceTag.getUsageCount());
        updateById(targetTag);

        // TODO: 更新所有使用源标签的任务，将其标签改为目标标签

        // 删除源标签
        removeById(sourceTagId);

        log.info("用户 {} 合并标签: {} -> {}", userId, sourceTag.getName(), targetTag.getName());
        
        return true;
    }

    /**
     * 转换为VO对象
     */
    private TaskTagVO convertToVO(TaskTag taskTag) {
        TaskTagVO vo = BeanCopyUtils.copyBean(taskTag, TaskTagVO.class);
        
        // 设置标签类型文本
        vo.setTagTypeText(getTagTypeText(taskTag.getTagType()));
        
        // 设置状态文本
        vo.setStatusText(getStatusText(taskTag.getStatus()));
        
        return vo;
    }

    /**
     * 获取标签类型文本
     */
    private String getTagTypeText(Integer tagType) {
        switch (tagType) {
            case 1: return "普通标签";
            case 2: return "系统标签";
            case 3: return "项目标签";
            default: return "未知";
        }
    }

    /**
     * 获取状态文本
     */
    private String getStatusText(Integer status) {
        switch (status) {
            case 1: return "有效";
            case 0: return "无效";
            default: return "未知";
        }
    }
}
